#

| Chapter 8 |

# 8. Conditionals, Loops, and Arrays

Contents:
Conditional Statements
Looping
Other Statements That Affect Flow Control
Arrays
An Acronym Processor
System Variables That Are Arrays

This chapter covers some fundamental programming constructs. It covers all the control statements in the awk programming language. It also covers arrays, variables that allow you to store a series of values. If this is your first exposure to such constructs, you'll recognize that even sed provided conditional and looping capabilities. In awk, these capabilities are much more generalized and the syntax is much easier to use. In fact, the syntax of awk's conditional and looping constructs is borrowed from the C programming language. Thus, by learning awk and the constructs in this chapter, you are also on the way to learning the C language.

## 8.1 Conditional Statements

A conditional statement allows you to make a test before performing an action. In the previous chapter, we saw examples of pattern matching rules that were essentially conditional expressions affecting the main input loop. In this section, we look at conditional statements used primarily within actions.

A conditional statement is introduced by `if` and evaluates an expression placed in parentheses. The syntax is:

> `if` ( `expression` )
> `action1`
> [`else`
> `action2`]

If expression evaluates as true (non-zero or non-empty), action1 is performed. When an `else` clause is specified, action2 is performed if expression evaluates to false (zero or empty). An expression might contain the arithmetic, relational, or Boolean operators discussed in Chapter 7, Writing Scripts for awk.

Perhaps the simplest conditional expression that you could write is one that tests whether a variable contains a non-zero value.

>     if ( x ) print x

If `x` is zero, the `print` statement will not be executed. If `x` has a non-zero value, that value will be printed. You can also test whether `x` equals another value:

>     if ( x == y ) print x

Remember that "==" is a relational operator and "=" is an assignment operator. We can also test whether `x` matches a pattern using the pattern-matching operator "~":

>     if ( x ~ /[yY](es)?/ ) print x

Here are a few additional syntactical points:

- If any action consists of more than one statement, the action is enclosed within a pair of braces.

  > `if` ( `expression` ) {
  > `statement1`
  > `statement2`
  > }

  Awk is not very particular about the placement of braces and statements (unlike sed). The opening brace is placed after the conditional expression, either on the same line or on the next line. The first statement can follow the opening brace or be placed on the line following it. The closing brace is put after the last statement, either on the same line or after it. Spaces or tabs are allowed before or after the braces. The indentation of statements is not required but is recommended to improve readability.

- A newline is optional after the close parenthesis, and after `else`.

  > `if` ( `expression` ) `action1`
  > [`else` `action2`]

- A newline is also optional after `action1`, providing that a semicolon ends action1.

  > `if` ( `expression` ) `action1`; [`else` `action2`]

- You cannot avoid using braces by using semicolons to separate multiple statements on a single line.

In the previous chapter, we saw a script that averaged student grades. We could use a conditional statement to tell us whether the student passed or failed.

Presuming that an average of 65 or above is a passing grade, we could write the following conditional:

>     if ( avg >= 65 )
>     	grade = "Pass"
>     else
>     	grade = "Fail"

The value assigned to `grade` depends upon whether the expression "avg >= 65" evaluates to true or false.

Multiple conditional statements can be used to test whether one of several possible conditions is true. For example, perhaps the students are given a letter grade instead of a pass-fail mark. Here's a conditional that assigns a letter grade based on a student's average:

>     if (avg >= 90)  grade = "A"
>     else if (avg >= 80) grade = "B"
>     else if (avg >= 70) grade = "C"
>     else if (avg >= 60) grade = "D"
>     else grade = "F"

The important thing to recognize is that successive conditionals like this are evaluated until one of them returns true; once that occurs, the rest of the conditionals are skipped. If none of the conditional expressions evaluates to true, the last `else` is accepted, constituting the default action; in this case, it assigns "F" to `grade`.

### 8.1.1 Conditional Operator

Awk provides a conditional operator that is found in the C programming language. Its form is:

> `expr` `?` `action1` `:` `action2`

The previous simple `if`/`else` condition can be written using a conditional operator:

>     grade = (avg >= 65) ? "Pass" : "Fail"

This form has the advantage of brevity and is appropriate for simple conditionals such as the one shown here. While the `?:` operator can be nested, doing so leads to programs that quickly become unreadable. For clarity, we recommend parenthesizing the conditional, as shown above.

7.11 Information Retrieval |  | 8.2 Looping